home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / UTILITY / XSPAWN.ARJ / XSPAWN.ASM < prev    next >
Assembly Source File  |  1991-05-04  |  52KB  |  1,394 lines

  1. ;
  2. ;                  XSPAWN
  3. ;               Version 1.33
  4. ; (C) Copyright 1990 Whitney Software, Inc.
  5. ;            All Rights Reserved
  6. ;
  7.  
  8. ; If you have increased the file handle table size so that more than 20 files
  9. ; may be open in the parent process, set FHTSZ to the new size.
  10.  
  11. FHTSZ           EQU     20
  12.  
  13. IFDEF LCODE
  14. ARG_1           EQU     6
  15. ELSE
  16. ARG_1           EQU     4
  17. ENDIF
  18.  
  19. arena           struc                           ; arena header
  20. sig             db      0                       ; 'M' or 'Z' if last block
  21. own             dw      0                       ; PSP of owner or 0 if free
  22. siz             dw      0                       ; size not including header
  23. arena           ends
  24.  
  25. vector          struc
  26. number          db      0                       ; vector number
  27. flag            db      0                       ; 0-CURRENT,1-IRET,2-free,3-end
  28. vseg            dw      0                       ; vector segment
  29. voff            dw      0                       ; vector offset
  30. vector          ends
  31.  
  32. _TEXT           SEGMENT word public 'CODE'
  33.                 ASSUME  cs:_TEXT
  34.                 ASSUME  ds:nothing
  35.                 ASSUME  es:nothing
  36.                 ASSUME  ss:nothing
  37.  
  38. ; The code between slidetop and slidebot constitutes the XSPAWN kernel.  The
  39. ; kernel is copied to the front of the parent process immediately following the
  40. ; parent's PSP.  The environment passed to the child is copied to immediately
  41. ; following the kernel.
  42.  
  43. slidetop:
  44.  
  45. path            db      'XSPAWN - (C) Copyright 1990 Whitney Software, Inc.'
  46.                 db      ' All Rights Reserved'
  47.                 db      9 dup (0)               ; 79 bytes total
  48. command         db      128 dup (0)             ; command-line
  49. file            db      79 dup (0)              ; swap file
  50.  
  51. parmblk         label   byte                    ; parameter block
  52. environ         dw      0                       ; environment block
  53. cmd             dw      0,0                     ; command-line tail
  54. fcb1            dw      0,0                     ; first file control block
  55. fcb2            dw      0,0                     ; second file control block
  56.  
  57. fcb5c           db      10h dup (0)             ; first file control block
  58. fcb6c           db      10h dup (0)             ; second file control block
  59.  
  60. cntsvl          dw      0                       ; count save low
  61. cntsvh          dw      0                       ; count save high
  62. tmpcode         dw      0                       ; temporary return code
  63. env             dw      0                       ; environment segment
  64. envlen          dw      0                       ; environment length
  65. parsz           dw      0                       ; parent size
  66. ttlsz           dw      0                       ; total size
  67. oldsz           dw      0                       ; old size
  68. newsz           dw      0                       ; new size
  69. emsseg          dw      0                       ; EMS page frame segment
  70. handle          dw      0                       ; EMS handle
  71. useems          db      0                       ; if 0, use EMS
  72. save            db      4 dup (0)               ; save 4 bytes at DS:[2Eh]
  73. f1add           dd      0                       ; fnish1 address
  74. last            db      0                       ; if 0, last block swap
  75. IF FHTSZ - 20
  76. fhtsv           db      FHTSZ dup (0)           ; file handle table save
  77. ENDIF
  78.  
  79. errmsg          db      'XSPAWN error',0Dh,0Ah
  80. msglen          EQU     $-errmsg
  81.  
  82.                 EVEN
  83. lclstk          dw      64 dup (0)              ; local stack
  84. stktop          label   word                    ; stack top
  85.  
  86. slide1:         mov     ax,cs                   ; install local stack
  87.                 cli
  88.                 mov     ss,ax
  89.                 mov     sp,offset stktop - offset slidetop + 100h
  90.                 sti
  91.  
  92. ; copy environment
  93.  
  94.                 mov     bx,offset slidebot - offset slidetop + 15 + 100h
  95.                 mov     cl,4
  96.                 shr     bx,cl                   ; convert to paragraphs
  97.                 add     bx,ax                   ; add CS (actually PSP)
  98. index = offset environ - offset slidetop + 100h
  99.                 mov     cs:[index],bx           ; parameter block
  100.                 mov     es,bx
  101.                 xor     di,di
  102. index = offset env - offset slidetop + 100h
  103.                 mov     ds,cs:[index]
  104.                 xor     si,si
  105. index = offset envlen - offset slidetop + 100h
  106.                 mov     cx,cs:[index]
  107.                 shr     cx,1                    ; translate to word count
  108.                 rep     movsw                   ; CF set if one byte left over
  109.                 adc     cx,cx                   ; CX = 1 or 0, depending CF
  110.                 rep     movsb                   ; possible final byte
  111.  
  112.                 dec     ax                      ; PSP segment
  113.                 mov     es,ax                   ; program arena header
  114.                 mov     bx,es:[siz]
  115. index = offset oldsz - offset slidetop + 100h
  116.                 mov     cs:[index],bx           ; old size
  117.                 mov     byte ptr es:[sig],'M'   ; not last
  118. index = offset newsz - offset slidetop + 100h
  119.                 mov     bx,cs:[index]           ; new size
  120.                 mov     es:[siz],bx
  121.  
  122.                 inc     ax                      ; PSP segment
  123.                 add     ax,bx                   ; add new size
  124.                 mov     es,ax                   ; new last arena header
  125.                 mov     byte ptr es:[sig],'Z'   ; last
  126. index = offset last - offset slidetop + 100h
  127.                 cmp     byte ptr cs:[index],0
  128.                 je      slide2                  ; jump if last block swap
  129.                 mov     byte ptr es:[sig],'M'   ; not last
  130.  
  131. slide2:         mov     word ptr es:[own],0     ; free
  132. index = offset ttlsz - offset slidetop + 100h
  133.                 mov     ax,cs:[index]           ; total size
  134.                 sub     ax,bx                   ; subtract new size
  135.                 dec     ax                      ; account for arena header
  136.                 mov     es:[siz],ax
  137.  
  138. ; save 4 bytes destroyed by DOS 2.0 at DS:2Eh
  139.  
  140.                 mov     ax,cs                   ; PSP segment
  141.                 mov     es,ax
  142.                 mov     bx,es:[2Eh]
  143. index = offset save - offset slidetop + 100h
  144.                 mov     cs:[index],bx
  145.                 mov     bx,es:[30h]
  146. index = offset save - offset slidetop + 102h
  147.                 mov     cs:[index],bx
  148.  
  149.                 mov     bx,offset parmblk - offset slidetop + 100h
  150.                 mov     ds,ax                   ; PSP segment
  151.                 mov     dx,100h                 ; offset path
  152.                 mov     ax,4B00h                ; load and execute program
  153.                 int     21h
  154.                 jnc     slide3                  ; jump if no error
  155. index = offset tmpcode - offset slidetop + 100h
  156.                 mov     cs:[index],ax           ; temporary return code
  157.  
  158. slide3:         mov     ax,cs                   ; install local stack
  159.                 cli
  160.                 mov     ss,ax
  161.                 mov     sp,offset stktop - offset slidetop + 100h
  162.                 sti
  163.  
  164. ; restore 4 bytes destroyed by DOS 2.0 at DS:2Eh
  165.  
  166.                 mov     es,ax                   ; PSP segment
  167. index = offset save - offset slidetop + 100h
  168.                 mov     bx,cs:[index]
  169.                 mov     es:[2Eh],bx
  170. index = offset save - offset slidetop + 102h
  171.                 mov     bx,cs:[index]
  172.                 mov     es:[30h],bx
  173.  
  174. index = offset oldsz - offset slidetop + 100h
  175.                 mov     bx,cs:[index]           ; old size
  176.                 mov     ah,4Ah                  ; resize memory block
  177.                 int     21h
  178.                 jnc     slide7
  179.  
  180. index = offset useems - offset slidetop + 100h
  181. slide4:         cmp     byte ptr cs:[index],0
  182.                 jne     slide6                  ; jump if don't use EMS
  183. index = offset handle - offset slidetop + 100h
  184.                 mov     dx,cs:[index]           ; EMS handle
  185.  
  186. slide5:         mov     ah,45h                  ; release handle and memory
  187.                 int     67h
  188.                 cmp     ah,82h                  ; memory manager busy?
  189.                 je      slide5                  ; jump if busy
  190.  
  191. slide6:         jmp     slide18                 ; exit
  192.  
  193. index = offset parsz - offset slidetop + 100h
  194. slide7:         mov     bx,cs:[index]           ; parent size
  195. index = offset ttlsz - offset slidetop + 100h
  196.                 mov     ax,cs:[index]           ; total size
  197.                 sub     ax,bx                   ; subtract parent size
  198.                 or      ax,ax
  199.                 jz      slide9
  200.                 mov     dx,cs                   ; PSP segment
  201.                 add     dx,bx                   ; add parent size
  202.                 mov     es,dx                   ; new last arena header
  203.                 mov     byte ptr es:[sig],'Z'   ; last
  204. index = offset last - offset slidetop + 100h
  205.                 cmp     byte ptr cs:[index],0
  206.                 je      slide8                  ; jump if last block swap
  207.                 mov     byte ptr es:[sig],'M'   ; not last
  208.  
  209. slide8:         mov     word ptr es:[own],0     ; free
  210.                 dec     ax                      ; account for arena header
  211.                 mov     es:[siz],ax
  212.  
  213. slide9:         push    cs                      ; PSP segment
  214. index = offset useems - offset slidetop + 100h
  215.                 cmp     byte ptr cs:[index],0
  216.                 jne     slide14                 ; jump if don't use EMS
  217.                 pop     es                      ; PSP segment
  218.                 mov     di,offset slidebot - offset slidetop + 100h
  219. index = offset emsseg - offset slidetop + 100h
  220.                 mov     ds,cs:[index]           ; EMS page frame segment
  221.                 mov     si,offset slidebot - offset slidetop
  222. index = offset handle - offset slidetop + 100h
  223.                 mov     dx,cs:[index]           ; EMS handle
  224.                 xor     bx,bx                   ; logical page number
  225.                 mov     cx,16384 - ( offset slidebot - offset slidetop )
  226.                 jmp     short slide13
  227.  
  228. index = offset cntsvl - offset slidetop + 100h
  229. slide10:        sub     cs:[index],cx
  230. index = offset cntsvh - offset slidetop + 100h
  231.                 sbb     word ptr cs:[index],0
  232.                 xor     al,al                   ; physical page number
  233.  
  234. slide11:        mov     ah,44h                  ; map memory
  235.                 int     67h
  236.                 or      ah,ah
  237.                 jz      slide12
  238.                 cmp     ah,82h                  ; memory manager busy?
  239.                 je      slide11                 ; jump if busy
  240.                 jmp     slide4                  ; exit
  241.  
  242. slide12:        shr     cx,1                    ; translate to word count
  243.                 rep     movsw                   ; CF set if one byte left over
  244.                 adc     cx,cx                   ; CX = 1 or 0, depending CF
  245.                 rep     movsb                   ; possible final byte
  246.                 xor     si,si
  247.                 mov     cx,16384                ; assume copy full block
  248.                 inc     bx                      ; logical page number
  249.                 cmp     bx,1
  250.                 je      slide13
  251.                 mov     ax,es
  252.                 add     ax,1024                 ; 16384 bytes
  253.                 mov     es,ax
  254.                 mov     di,16640                ; 16384 + 100h
  255.  
  256. index = offset cntsvh - offset slidetop + 100h
  257. slide13:        cmp     word ptr cs:[index],0
  258.                 jne     slide10                 ; jump if more than full block
  259. index = offset cntsvl - offset slidetop + 100h
  260.                 cmp     cs:[index],cx
  261.                 jae     slide10                 ; jump if at least full block
  262.                 mov     cx,cs:[index]           ; CX = cntsvl
  263.                 cmp     cx,0
  264.                 jne     slide10                 ; jump if more left to copy
  265.                 jmp     short slide17
  266.  
  267. slide14:        pop     ds                      ; PSP segment
  268. IF FHTSZ - 20
  269.  
  270. ; restore the file handle table from the kernel
  271.  
  272.                 mov     si,offset fhtsv - offset slidetop + 100h
  273.                 mov     es,ds:[36h]             ; file handle table segment
  274.                 mov     di,ds:[34h]             ; file handle table offset
  275.                 mov     cx,FHTSZ                ; file handle table size
  276.                 rep     movsb
  277. ENDIF
  278.                 mov     dx,offset file - offset slidetop + 100h
  279.                 mov     ax,3D00h                ; open file read only
  280.                 int     21h
  281.                 jc      slide18                 ; exit if error
  282.                 mov     bx,ax                   ; handle
  283.  
  284.                 xor     cx,cx
  285.                 mov     dx,offset slidebot - offset slidetop
  286.                 mov     ax,4200h                ; move file pointer
  287.                 int     21h                     ;  from beginning of file
  288.  
  289.                 mov     dx,offset slidebot - offset slidetop + 100h
  290.                 mov     cx,65520                ; assume read full block
  291.                 jmp     short slide16
  292.  
  293. index = offset cntsvl - offset slidetop + 100h
  294. slide15:        sub     cs:[index],cx
  295. index = offset cntsvh - offset slidetop + 100h
  296.                 sbb     word ptr cs:[index],0
  297.                 mov     ah,3Fh                  ; read file
  298.                 int     21h
  299.                 jc      slide18                 ; exit if error
  300.                 cmp     ax,cx
  301.                 jne     slide18                 ; exit if not all read
  302.  
  303.                 mov     ax,ds
  304.                 add     ax,4095                 ; 65520 bytes
  305.                 mov     ds,ax
  306.  
  307. index = offset cntsvh - offset slidetop + 100h
  308. slide16:        cmp     word ptr cs:[index],0
  309.                 jne     slide15                 ; jump if more than full block
  310. index = offset cntsvl - offset slidetop + 100h
  311.                 cmp     word ptr cs:[index],65520
  312.                 jae     slide15                 ; jump if at least full block
  313.                 mov     cx,cs:[index]           ; CX = cntsvl
  314.                 cmp     cx,0
  315.                 jne     slide15                 ; jump if more left to read
  316.  
  317. index = offset tmpcode - offset slidetop + 100h
  318. slide17:        mov     ax,cs:[index]           ; temporary return code
  319. index = offset f1add - offset slidetop + 100h
  320.                 jmp     dword ptr cs:[index]
  321.  
  322. slide18:        push    cs                      ; PSP segment
  323.                 pop     ds
  324.                 mov     dx,offset errmsg - offset slidetop + 100h
  325.                 mov     cx,msglen               ; errmsg length
  326.                 mov     bx,2                    ; standard error device handle
  327.                 mov     ah,40h                  ; write error message
  328.                 int     21h
  329.                 mov     ax,4C01h                ; terminate with return code
  330.                 int     21h
  331.  
  332. handler:        iret                            ; interrupt handler
  333.  
  334. slidebot:
  335.  
  336. cntl            dw      0                       ; count low
  337. cnth            dw      0                       ; count high
  338. stks            dw      0                       ; original SS contents
  339. stkp            dw      0                       ; original SP contents
  340. psp             dw      0                       ; PSP segment
  341. s1add           dd      0                       ; slide1 address
  342. rcode           dw      0                       ; return code
  343. useems2         db      0                       ; if 0, use EMS
  344. vtabseg         dw      0                       ; vectab1 segment
  345. vtaboff         dw      0                       ; vectab1 offset
  346.  
  347. errmsg2         db      'XSPAWN error',0Dh,0Ah
  348. msglen2         EQU     $-errmsg2
  349.  
  350. ;
  351. ; int _xspawn( char *, char *, char *, VECTOR *, int, int, char *, int );
  352. ;
  353.  
  354.                 PUBLIC  __xspawn
  355. IFDEF LCODE
  356. __xspawn        PROC    far
  357. ELSE
  358. __xspawn        PROC    near
  359. ENDIF
  360.  
  361.                 push    bp
  362.                 mov     bp,sp
  363.                 push    di                      ; preserve register variables
  364.                 push    si
  365.                 push    ds
  366.  
  367. IFDEF LDATA
  368.                 lds     si,dword ptr [bp+ARG_1]
  369. ELSE
  370.                 mov     si,word ptr [bp+ARG_1]
  371. ENDIF
  372.                 mov     di,offset path
  373.  
  374. start1:         mov     al,ds:[si]              ; copy path string
  375.                 mov     cs:[di],al              ;  to code segment
  376.                 inc     si
  377.                 inc     di
  378.                 or      al,al                   ; null char?
  379.                 jnz     start1                  ; no, get next char
  380.  
  381. IFDEF LDATA
  382.                 lds     si,dword ptr [bp+ARG_1+4]
  383. ELSE
  384.                 mov     si,word ptr [bp+ARG_1+2]
  385. ENDIF
  386.                 mov     bx,si                   ; preserve si
  387.                 mov     di,offset command
  388.                 mov     cx,2                    ; account for count and '\r'
  389.                 add     cl,byte ptr ds:[bx]     ; add count byte
  390.  
  391. start2:         mov     al,ds:[bx]              ; copy command
  392.                 mov     cs:[di],al              ;  to code segment
  393.                 inc     bx
  394.                 inc     di
  395.                 loop    start2                  ; get next char
  396.  
  397.                 inc     si                      ; skip count byte
  398.                 push    cs
  399.                 pop     es
  400.                 mov     di,offset fcb5c
  401.                 mov     ax,2901h                ; parse filename
  402.                 int     21h                     ;  skip leading separators
  403.                 mov     di,offset fcb6c
  404.                 mov     al,1                    ; parse filename
  405.                 int     21h                     ;  skip leading separators
  406.  
  407. IFDEF LDATA
  408.                 mov     ax,word ptr [bp+ARG_1+8]
  409. ELSE
  410.                 mov     ax,word ptr [bp+ARG_1+4]
  411. ENDIF
  412.                 mov     cl,4
  413.                 shr     ax,cl                   ; convert to paragraphs
  414. IFDEF LDATA
  415.                 mov     bx,word ptr [bp+ARG_1+10]
  416. ELSE
  417.                 mov     bx,ds
  418. ENDIF
  419.                 add     ax,bx
  420.                 mov     cs:[env],ax             ; environment segment
  421.  
  422. IFDEF LDATA
  423.                 lds     bx,dword ptr [bp+ARG_1+12] ; vectab1
  424. ELSE
  425.                 mov     bx,word ptr [bp+ARG_1+6] ; vectab1
  426. ENDIF
  427.                 mov     cs:[vtabseg],ds         ; vectab1 segment
  428.                 mov     cs:[vtaboff],bx         ; vectab1 offset
  429.  
  430.                 mov     cs:[stks],ss            ; original SS contents
  431.                 mov     cs:[stkp],sp            ; original SP contents
  432.                 mov     cs:[rcode],0            ; assume success
  433.  
  434. IFDEF LDATA
  435.                 mov     ax,word ptr [bp+ARG_1+16]
  436. ELSE
  437.                 mov     ax,word ptr [bp+ARG_1+8]
  438. ENDIF
  439.                 or      ax,ax                   ; do swap?
  440.                 jz      start3                  ; yes, jump
  441.                 jmp     noswap1
  442.  
  443. IFDEF LDATA
  444. start3:         mov     ax,word ptr [bp+ARG_1+18]
  445. ELSE
  446. start3:         mov     ax,word ptr [bp+ARG_1+10]
  447. ENDIF
  448.                 mov     cs:[envlen],ax          ; environment length
  449.                 add     ax,offset slidebot - offset slidetop + 30 + 100h
  450.                 mov     cl,4
  451.                 shr     ax,cl                   ; convert to paragraphs
  452.                 mov     cs:[newsz],ax           ; new size
  453.  
  454. IFDEF LDATA
  455.                 lds     si,dword ptr [bp+ARG_1+20]
  456. ELSE
  457.                 mov     si,word ptr [bp+ARG_1+12]
  458. ENDIF
  459.                 mov     di,offset file
  460.                 mov     cs:[useems2],1          ; assume don't use EMS
  461.                 cmp     byte ptr ds:[si],0
  462.                 jne     start4
  463.                 mov     cs:[useems2],0          ; use EMS
  464.  
  465. start4:         mov     al,ds:[si]              ; copy file string
  466.                 mov     cs:[di],al              ;  to code segment
  467.                 inc     si
  468.                 inc     di
  469.                 or      al,al                   ; null char?
  470.                 jnz     start4                  ; no, get next char
  471.  
  472. ; save fnish1 address
  473.  
  474.                 mov     word ptr cs:[f1add+2],cs
  475.                 mov     word ptr cs:[f1add],offset fnish1
  476.  
  477. ; initialize parameter block
  478.  
  479.                 mov     ax,cs:[psp]             ; PSP segment
  480.                 mov     cs:[cmd],offset command - offset slidetop + 100h
  481.                 mov     cs:[cmd+2],ax
  482.                 mov     cs:[fcb1],offset fcb5c - offset slidetop + 100h
  483.                 mov     cs:[fcb1+2],ax
  484.                 mov     cs:[fcb2],offset fcb6c - offset slidetop + 100h
  485.                 mov     cs:[fcb2+2],ax
  486.  
  487.                 cld                             ; left to right direction
  488.  
  489.                 mov     ds,ax                   ; PSP segment
  490. IFDEF LDATA
  491.                 mov     dx,word ptr [bp+ARG_1+24]
  492. ELSE
  493.                 mov     dx,word ptr [bp+ARG_1+14]
  494. ENDIF
  495. IF FHTSZ - 20
  496.                 cmp     word ptr ds:[32h],FHTSZ ; file handle table size
  497.                 je      start5                  ; jump if OK
  498.                 mov     cs:[rcode],5
  499.                 jmp     short start6
  500. ENDIF
  501.  
  502. start5:         mov     ax,cs:[newsz]           ; new size
  503.                 cmp     ax,cs:[ttlsz]           ; new size < total size?
  504.                 jb      start8                  ; yes, jump
  505.                 mov     cs:[rcode],7            ; extremely unlikely
  506.  
  507. start6:         cmp     cs:[useems2],0
  508.                 jne     start7                  ; jump if don't use EMS
  509.                 jmp     fnish2
  510.  
  511. start7:         mov     bx,dx                   ; file handle
  512.                 jmp     fnish6
  513.  
  514. start8:         cmp     cs:[useems2],0
  515.                 jne     start12                 ; jump if don't use EMS
  516.                 mov     cs:[useems],0           ; use EMS
  517.                 mov     cs:[handle],dx          ; EMS handle
  518.                 mov     es,cs:[emsseg]          ; EMS page frame segment
  519.                 xor     bx,bx                   ; logical page number
  520.                 jmp     short start11
  521.  
  522. start9:         sub     cs:[cntl],cx
  523.                 sbb     cs:[cnth],0
  524.                 call    mapems
  525.                 or      ah,ah
  526.                 jz      start10                 ; jump if map succeeded
  527.                 jmp     fnish2
  528.  
  529. start10:        mov     si,100h
  530.                 xor     di,di
  531.                 shr     cx,1                    ; translate to word count
  532.                 rep     movsw                   ; CF set if one byte left over
  533.                 adc     cx,cx                   ; CX = 1 or 0, depending CF
  534.                 rep     movsb                   ; possible final byte
  535.                 inc     bx                      ; logical page number
  536.                 mov     ax,ds
  537.                 add     ax,1024                 ; 16384 bytes
  538.                 mov     ds,ax
  539.  
  540. start11:        mov     cx,16384                ; assume copy full block
  541.                 cmp     cs:[cnth],0
  542.                 jne     start9                  ; jump if more than full block
  543.                 cmp     cs:[cntl],16384
  544.                 jae     start9                  ; jump if at least full block
  545.                 mov     cx,cs:[cntl]
  546.                 cmp     cx,0
  547.                 jne     start9                  ; jump if more left to copy
  548.                 jmp     short start17
  549.  
  550. start12:        mov     cs:[useems],1           ; don't use EMS
  551.                 mov     bx,dx                   ; handle
  552.                 mov     dx,100h                 ; DS:DX segment:offset buffer
  553.                 mov     cx,65520                ; assume write full block
  554.                 jmp     short start16
  555.  
  556. start13:        sub     cs:[cntl],cx
  557.                 sbb     cs:[cnth],0
  558.                 mov     ah,40h                  ; write file
  559.                 int     21h
  560.                 jc      start14                 ; jump if error
  561.                 cmp     ax,cx
  562.                 je      start15                 ; jump if all written
  563.  
  564. start14:        mov     ah,3Eh                  ; close file
  565.                 int     21h
  566.                 mov     cs:[rcode],5
  567.                 jmp     fnish7
  568.  
  569. start15:        mov     ax,ds
  570.                 add     ax,4095                 ; 65520 bytes
  571.                 mov     ds,ax
  572.  
  573. start16:        cmp     cs:[cnth],0
  574.                 jne     start13                 ; jump if more than full block
  575.                 cmp     cs:[cntl],65520
  576.                 jae     start13                 ; jump if at least full block
  577.                 mov     cx,cs:[cntl]
  578.                 cmp     cx,0
  579.                 jne     start13                 ; jump if more left to write
  580.  
  581.                 mov     ah,3Eh                  ; close file
  582.                 int     21h
  583. IF FHTSZ - 20
  584.  
  585. ; save the file handle table in the kernel
  586.  
  587.                 mov     es,cs:[psp]             ; PSP segment
  588.                 mov     ds,es:[36h]             ; file handle table segment
  589.                 mov     si,es:[34h]             ; file handle table offset
  590.                 push    cs
  591.                 pop     es
  592.                 mov     di,offset fhtsv         ; file handle table save
  593.                 mov     cx,FHTSZ                ; file handle table size
  594.                 rep     movsb
  595. ENDIF
  596.  
  597. start17:        mov     cx,cs
  598.                 mov     dx,offset handler       ; interrupt handler offset
  599.                 call    safevect                ; set vectors in vectab1
  600.  
  601. ; time to copy the kernel
  602.  
  603.                 mov     es,cs:[psp]             ; PSP segment
  604.                 mov     di,100h
  605.                 mov     ds,cx                   ; DS = CS
  606.                 mov     si,offset slidetop
  607.                 mov     cx,offset slidebot - offset slidetop
  608.                 shr     cx,1                    ; translate to word count
  609.                 rep     movsw                   ; CF set if one byte left over
  610.                 adc     cx,cx                   ; CX = 1 or 0, depending CF
  611.                 rep     movsb                   ; possible final byte
  612.  
  613.                 mov     word ptr cs:[s1add+2],es ; PSP segment
  614. index = offset slide1 - offset slidetop + 100h
  615.                 mov     word ptr cs:[s1add],index ; slide1 offset
  616.  
  617.                 mov     cx,es                   ; PSP segment
  618. index = offset handler - offset slidetop + 100h
  619.                 mov     dx,index                ; interrupt handler offset
  620.                 call    safevect                ; set vectors in vectab1
  621.  
  622.                 jmp     dword ptr cs:[s1add]    ; jump to the kernel
  623.  
  624. ; If all goes well, this is where we come back to from the kernel.
  625.  
  626. fnish1:         mov     cs:[rcode],ax           ; return code
  627.  
  628.                 cli                             ; restore original stack
  629.                 mov     ss,cs:[stks]
  630.                 mov     sp,cs:[stkp]
  631.                 sti
  632.  
  633.                 push    ds                      ; maybe EMS page frame segment
  634.                 push    dx                      ; maybe EMS handle
  635.                 push    bx                      ; maybe swap file handle
  636.                 mov     cx,cs
  637.                 mov     dx,offset handler       ; interrupt handler offset
  638.                 call    safevect                ; set vectors in vectab1
  639.                 pop     bx
  640.                 pop     dx
  641.                 pop     ds
  642.  
  643.                 cmp     cs:[useems2],0
  644.                 jne     fnish4                  ; jump if don't use EMS
  645.  
  646. ; DS = EMS page frame segment
  647. ; DX = EMS handle
  648.  
  649.                 mov     cx,offset slidebot - offset slidetop
  650.                 mov     es,cs:[psp]             ; PSP segment
  651.                 mov     di,100h
  652.                 xor     si,si
  653.                 xor     bx,bx                   ; logical page number
  654.                 call    mapems
  655.                 or      ah,ah
  656.                 jnz     fnish3                  ; jump if map failed
  657.                 shr     cx,1                    ; translate to word count
  658.                 rep     movsw                   ; CF set if one byte left over
  659.                 adc     cx,cx                   ; CX = 1 or 0, depending CF
  660.                 rep     movsb                   ; possible final byte
  661.  
  662. fnish2:         mov     ah,45h                  ; release handle and memory
  663.                 int     67h
  664.                 cmp     ah,82h                  ; memory manager busy?
  665.                 je      fnish2                  ; jump if busy
  666.                 jmp     short fnish7
  667.  
  668. fnish3:         mov     ah,45h                  ; release handle and memory
  669.                 int     67h
  670.                 cmp     ah,82h                  ; memory manager busy?
  671.                 je      fnish3                  ; jump if busy
  672.                 jmp     short fnish5            ; exit
  673.  
  674. ; BX = swap file handle
  675.  
  676. fnish4:         xor     cx,cx                   ; offset 0
  677.                 xor     dx,dx                   ; offset 0
  678.                 mov     ax,4200h                ; move file pointer
  679.                 int     21h                     ;  from beginning of file
  680.  
  681.                 mov     cx,offset slidebot - offset slidetop
  682.                 mov     ds,cs:[psp]             ; PSP segment
  683.                 mov     dx,100h
  684.                 mov     ah,3Fh                  ; read file
  685.                 int     21h
  686.                 jc      fnish5                  ; exit if error
  687.                 cmp     ax,cx
  688.                 je      fnish6
  689.  
  690. fnish5:         push    cs
  691.                 pop     ds
  692.                 mov     dx,offset errmsg2
  693.                 mov     cx,msglen2              ; errmsg2 length
  694.                 mov     bx,2                    ; standard error device handle
  695.                 mov     ah,40h                  ; write error message
  696.                 int     21h
  697.                 mov     ax,4C01h                ; terminate with return code
  698.                 int     21h
  699.  
  700. fnish6:         mov     ah,3Eh                  ; close file
  701.                 int     21h
  702.                 push    cs
  703.                 pop     ds
  704.                 mov     dx,offset file
  705.                 mov     ah,41h                  ; delete file
  706.                 int     21h
  707.  
  708. fnish7:         pop     ds
  709.                 pop     si                      ; restore register variables
  710.                 pop     di
  711.                 pop     bp
  712.  
  713.                 mov     ax,cs:[rcode]           ; return code
  714.                 or      ax,ax
  715.                 jz      fnish11
  716.                 push    ax
  717.                 mov     ax,3000h                ; get DOS version number
  718.                 int     21h
  719.                 cmp     al,3                    ; major version number
  720.                 pop     ax
  721.                 jb      fnish8
  722.                 cmp     al,34                   ; unknown error - 3.0
  723.                 jae     fnish9
  724.                 cmp     al,32                   ; sharing violation
  725.                 jb      fnish8
  726.                 mov     al,5                    ; access denied
  727.                 jmp     short fnish10
  728.  
  729. fnish8:         cmp     al,19                   ; unknown error - 2.0
  730.                 jbe     fnish10
  731.  
  732. fnish9:         mov     al,19                   ; unknown error - 2.0
  733.  
  734. fnish10:        xor     ah,ah
  735.  
  736. fnish11:        ret
  737.  
  738. ; If we are not swapping, we jump here.
  739.  
  740. noswap1:        mov     ax,cs
  741.  
  742. ; initialize parameter block
  743.  
  744.                 mov     bx,cs:[env]
  745.                 mov     cs:[environ],bx
  746.                 mov     cs:[cmd],offset command
  747.                 mov     cs:[cmd+2],ax
  748.                 mov     cs:[fcb1],offset fcb5c
  749.                 mov     cs:[fcb1+2],ax
  750.                 mov     cs:[fcb2],offset fcb6c
  751.                 mov     cs:[fcb2+2],ax
  752.  
  753. ; save 4 bytes destroyed by DOS 2.0 at DS:2Eh
  754.  
  755.                 mov     si,cs:[2Eh]
  756.                 mov     word ptr cs:[save],si
  757.                 mov     si,cs:[30h]
  758.                 mov     word ptr cs:[save+2],si
  759.  
  760.                 mov     cx,cs
  761.                 mov     dx,offset handler       ; interrupt handler offset
  762.                 call    safevect                ; set vectors in vectab1
  763.  
  764.                 mov     es,cx                   ; ES = CS
  765.                 mov     bx,offset parmblk
  766.                 mov     ds,cx                   ; DS = CS
  767.                 mov     dx,offset path
  768.                 mov     ax,4B00h                ; load and execute program
  769.                 int     21h
  770.                 jnc     noswap2                 ; jump if no error
  771.                 mov     cs:[rcode],ax           ; return code
  772.  
  773. noswap2:        cli                             ; restore original stack
  774.                 mov     ss,cs:[stks]
  775.                 mov     sp,cs:[stkp]
  776.                 sti
  777.  
  778. ; restore 4 bytes destroyed by DOS 2.0 at DS:2Eh
  779.  
  780.                 mov     si,word ptr cs:[save]
  781.                 mov     cs:[2Eh],si
  782.                 mov     si,word ptr cs:[save+2]
  783.                 mov     cs:[30h],si
  784.  
  785.                 jmp     fnish7
  786.  
  787. __xspawn        ENDP
  788.  
  789. mapems          PROC    near
  790.  
  791. ; DX = handle
  792. ; BX = logical page number
  793.  
  794.                 xor     al,al                   ; physical page number
  795.  
  796. map1:           mov     ah,44h                  ; map memory
  797.                 int     67h
  798.                 cmp     ah,82h                  ; memory manager busy?
  799.                 je      map1                    ; jump if busy
  800.  
  801.                 ret
  802.  
  803. mapems          ENDP
  804.  
  805. setvectsub      PROC    near
  806.  
  807. ; ES = vector table segment
  808. ; BX = vector table offset
  809.  
  810.                 mov     ah,25h                  ; set interrupt vector
  811.  
  812. setvectsub1:    mov     al,es:[bx+flag]         ; 0-CURRENT,1-IRET,2-free,3-end
  813.                 cmp     al,3                    ; is it the end?
  814.                 je      setvectsub3             ; yes, jump
  815.                 cmp     al,2                    ; is it free?
  816.                 je      setvectsub2             ; yes, jump
  817.                 mov     al,es:[bx+number]       ; vector number
  818.                 mov     ds,es:[bx+vseg]         ; vector segment
  819.                 mov     dx,es:[bx+voff]         ; vector offset
  820.                 int     21h                     ; set interrupt vector
  821.  
  822. setvectsub2:    add     bx,6                    ; size of vector structure
  823.                 jmp     setvectsub1             ; next
  824.  
  825. setvectsub3:    ret
  826.  
  827. setvectsub      ENDP
  828.  
  829. safevect        PROC    near
  830.  
  831. ; CX = handler segment
  832. ; DX = handler offset
  833.  
  834.                 mov     es,cs:[vtabseg]         ; vectab1 segment
  835.                 mov     bx,cs:[vtaboff]         ; vectab1 offset
  836.  
  837. safevect1:      mov     al,es:[bx+flag]         ; 0-CURRENT,1-IRET,2-free,3-end
  838.                 cmp     al,3                    ; is it the end?
  839.                 je      safevect3               ; yes, jump
  840.                 cmp     al,1                    ; is it IRET?
  841.                 jne     safevect2               ; no, jump
  842.                 mov     es:[bx+vseg],cx         ; handler segment
  843.                 mov     es:[bx+voff],dx         ; handler offset
  844.  
  845. safevect2:      add     bx,6                    ; size of vector structure
  846.                 jmp     safevect1               ; next
  847.  
  848. safevect3:      mov     bx,cs:[vtaboff]         ; vectab1 offset
  849.                 call    setvectsub
  850.  
  851.                 ret
  852.  
  853. safevect        ENDP
  854.  
  855. ;
  856. ; int _xsize( unsigned int, long *, long * );
  857. ;
  858.  
  859.                 PUBLIC  __xsize
  860. IFDEF LCODE
  861. __xsize         PROC    far
  862. ELSE
  863. __xsize         PROC    near
  864. ENDIF
  865.  
  866.                 push    bp
  867.                 mov     bp,sp
  868.                 push    di                      ; preserve register variables
  869.                 push    si
  870.                 push    ds
  871.  
  872.                 mov     cs:[last],0             ; assume last block swap
  873.                 mov     bx,word ptr [bp+ARG_1]  ; PSP segment
  874.                 mov     cs:[psp],bx
  875.                 mov     dx,bx
  876.                 dec     bx                      ; program arena header
  877.  
  878. size1:          mov     es,bx                   ; current arena header
  879.                 mov     ax,es:[own]
  880.                 or      ax,ax                   ; is it free?
  881.                 jz      size2                   ; yes, count it
  882.                 cmp     ax,dx                   ; do we own it?
  883.                 jne     size4                   ; no, jump
  884.                 mov     cx,bx                   ; last owned block
  885.  
  886. size2:          inc     bx
  887.                 add     bx,es:[siz]             ; block size
  888.                 jc      size3                   ; carry, arena is trashed
  889.                 mov     al,es:[sig]             ; get arena signature
  890.                 cmp     al,'M'                  ; are we at end of memory?
  891.                 je      size1                   ; no, jump
  892.                 cmp     al,'Z'
  893.                 je      size5
  894.  
  895. size3:          mov     bx,-1                   ; request maximum memory
  896.                 mov     ah,48h                  ; allocate memory block
  897.                 int     21h
  898.                 mov     cs:[rcode],7
  899.                 jmp     fnish7
  900.  
  901. size4:          mov     cs:[last],1             ; not last block swap
  902.  
  903. size5:          sub     bx,dx                   ; subtract PSP segment
  904.                 mov     ax,cx                   ; last owned block
  905.                 mov     es,cx
  906.                 inc     ax
  907.                 add     ax,es:[siz]             ; block size
  908.                 sub     ax,dx                   ; subtract PSP segment
  909.                 mov     cs:[parsz],ax           ; parent size
  910.                 sub     ax,10h                  ; subtract PSP size
  911.                 xor     dx,dx                   ; convert to bytes
  912.                 mov     cx,4
  913.  
  914. size6:          shl     ax,1
  915.                 rcl     dx,1
  916.                 loop    size6
  917. IFDEF LDATA
  918.                 lds     si,dword ptr [bp+ARG_1+2]
  919. ELSE
  920.                 mov     si,word ptr [bp+ARG_1+2]
  921. ENDIF
  922.                 mov     ds:[si],ax              ; swap size requirement
  923.                 mov     ds:[si+2],dx
  924.                 mov     cs:[cntl],ax            ; count low
  925.                 mov     cs:[cnth],dx            ; count high
  926.                 mov     cx,offset slidebot - offset slidetop
  927.                 sub     ax,cx
  928.                 sbb     dx,0
  929.                 mov     cs:[cntsvl],ax          ; count save low
  930.                 mov     cs:[cntsvh],dx          ; count save high
  931.                 mov     cs:[ttlsz],bx           ; total size
  932.                 xor     dx,dx                   ; convert to bytes
  933.                 mov     cx,4
  934.  
  935. size7:          shl     bx,1
  936.                 rcl     dx,1
  937.                 loop    size7
  938. IFDEF LDATA
  939.                 lds     si,dword ptr [bp+ARG_1+6]
  940. ELSE
  941.                 mov     si,word ptr [bp+ARG_1+4]
  942. ENDIF
  943.                 mov     ds:[si],bx              ; parent and free memory
  944.                 mov     ds:[si+2],dx
  945.  
  946.                 pop     ds
  947.                 pop     si                      ; restore register variables
  948.                 pop     di
  949.                 pop     bp
  950.                 xor     ax,ax
  951.                 ret
  952.  
  953. __xsize         ENDP
  954.  
  955. ;
  956. ; int _chkems( char *, int * );
  957. ;
  958.  
  959.                 PUBLIC  __chkems
  960. IFDEF LCODE
  961. __chkems        PROC    far
  962. ELSE
  963. __chkems        PROC    near
  964. ENDIF
  965.  
  966.                 push    bp
  967.                 mov     bp,sp
  968.  
  969. ; determine whether expanded memory is available
  970.  
  971. IFDEF LDATA
  972.                 push    ds
  973.                 lds     dx,dword ptr [bp+ARG_1] ; EMM device driver name
  974. ELSE
  975.                 mov     dx,word ptr [bp+ARG_1]  ; EMM device driver name
  976. ENDIF
  977.                 mov     ax,3D00h                ; open file read only
  978.                 int     21h
  979. IFDEF LDATA
  980.                 pop     ds
  981. ENDIF
  982.                 jc      check2                  ; expanded memory unavailable
  983.  
  984. ; determine whether we opened the EMM device driver or a file
  985.  
  986.                 mov     bx,ax                   ; handle
  987.                 mov     ax,4400h                ; IOCTL - get device info
  988.                 int     21h
  989.                 jc      check1                  ; expanded memory unavailable
  990.                 test    dx,80h                  ; test bit 7
  991.                 jz      check1                  ; expanded memory unavailable
  992.  
  993.                 mov     ax,4407h                ; IOCTL - get output status
  994.                 int     21h
  995.                 jc      check1                  ; expanded memory unavailable
  996.                 or      al,al
  997.                 jz      check1                  ; expanded memory unavailable
  998.  
  999. ; close EMM device driver to reclaim handle
  1000.  
  1001.                 mov     ah,3Eh                  ; close file
  1002.                 int     21h
  1003.  
  1004. ; determine whether the EMM is functional
  1005.  
  1006.                 mov     ah,40h                  ; get manager status
  1007.                 int     67h
  1008.                 or      ah,ah
  1009.                 jnz     check2                  ; expanded memory unavailable
  1010.  
  1011. ; check EMM version
  1012.  
  1013.                 mov     ah,46h                  ; get EMM version
  1014.                 int     67h
  1015.                 or      ah,ah
  1016.                 jnz     check2                  ; expanded memory unavailable
  1017.                 cmp     al,32h                  ; version 3.2
  1018.                 jb      check2                  ; expanded memory unavailable
  1019.  
  1020. ; get page frame segment
  1021.  
  1022.                 mov     ah,41h                  ; get page frame segment
  1023.                 int     67h
  1024.                 or      ah,ah
  1025.                 jnz     check2                  ; expanded memory unavailable
  1026.                 mov     cs:[emsseg],bx          ; segment
  1027.  
  1028. ; get size of page map information
  1029.  
  1030.                 mov     ax,4E03h                ; get size of page map info
  1031.                 int     67h
  1032.                 or      ah,ah
  1033.                 jnz     check2                  ; expanded memory unavailable
  1034. IFDEF LDATA
  1035.                 les     bx,dword ptr [bp+ARG_1+4] ; mapsize address
  1036.                 mov     es:[bx],ax
  1037. ELSE
  1038.                 mov     bx,word ptr [bp+ARG_1+2] ; mapsize address
  1039.                 mov     ds:[bx],ax
  1040. ENDIF
  1041.                 xor     ax,ax                   ; expanded memory available
  1042.                 pop     bp
  1043.                 ret
  1044.  
  1045. ; close EMM device driver or file to reclaim handle
  1046.  
  1047. check1:         mov     ah,3Eh                  ; close file
  1048.                 int     21h
  1049.  
  1050. check2:         mov     ax,1                    ; expanded memory unavailable
  1051.                 pop     bp
  1052.                 ret
  1053.  
  1054. __chkems        ENDP
  1055.  
  1056. ;
  1057. ; int _savemap( char * );
  1058. ;
  1059.  
  1060.                 PUBLIC  __savemap
  1061. IFDEF LCODE
  1062. __savemap       PROC    far
  1063. ELSE
  1064. __savemap       PROC    near
  1065. ENDIF
  1066.  
  1067.                 push    bp
  1068.                 mov     bp,sp
  1069.                 push    di                      ; preserve register variable
  1070.  
  1071. IFDEF LDATA
  1072.                 les     di,dword ptr [bp+ARG_1] ; buffer address
  1073. ELSE
  1074.                 mov     di,word ptr [bp+ARG_1]  ; buffer address
  1075.                 push    ds
  1076.                 pop     es
  1077. ENDIF
  1078.                 mov     ax,4E00h                ; save page map
  1079.                 int     67h
  1080.  
  1081.                 pop     di                      ; restore register variable
  1082.                 pop     bp
  1083.                 ret
  1084.  
  1085. __savemap       ENDP
  1086.  
  1087. ;
  1088. ; int _restmap( char * );
  1089. ;
  1090.  
  1091.                 PUBLIC  __restmap
  1092. IFDEF LCODE
  1093. __restmap       PROC    far
  1094. ELSE
  1095. __restmap       PROC    near
  1096. ENDIF
  1097.  
  1098.                 push    bp
  1099.                 mov     bp,sp
  1100.                 push    ds
  1101.                 push    si                      ; preserve register variable
  1102.  
  1103. IFDEF LDATA
  1104.                 lds     si,dword ptr [bp+ARG_1] ; buffer address
  1105. ELSE
  1106.                 mov     si,word ptr [bp+ARG_1]  ; buffer address
  1107. ENDIF
  1108.                 mov     ax,4E01h                ; restore page map
  1109.                 int     67h
  1110.                 xor     al,al
  1111.  
  1112.                 pop     si                      ; restore register variable
  1113.                 pop     ds
  1114.                 pop     bp
  1115.                 ret
  1116.  
  1117. __restmap       ENDP
  1118.  
  1119. ;
  1120. ; int _getems( int, int * );
  1121. ;
  1122.  
  1123.                 PUBLIC  __getems
  1124. IFDEF LCODE
  1125. __getems        PROC    far
  1126. ELSE
  1127. __getems        PROC    near
  1128. ENDIF
  1129.  
  1130.                 push    bp
  1131.                 mov     bp,sp
  1132.  
  1133.                 mov     bx,word ptr [bp+ARG_1]  ; number of pages
  1134.                 mov     ah,43h                  ; get handle and allocate
  1135.                                                 ;  memory
  1136.                 int     67h
  1137. IFDEF LDATA
  1138.                 les     bx,dword ptr [bp+ARG_1+2] ; handle address
  1139.                 mov     es:[bx],dx              ; handle
  1140. ELSE
  1141.                 mov     bx,word ptr [bp+ARG_1+2] ; handle address
  1142.                 mov     ds:[bx],dx              ; handle
  1143. ENDIF
  1144.                 xor     al,al
  1145.                 pop     bp
  1146.                 ret
  1147.  
  1148. __getems        ENDP
  1149.  
  1150. ;
  1151. ; int _dskspace( int, unsigned int *, unsigned int * );
  1152. ;
  1153.  
  1154.                 PUBLIC  __dskspace
  1155. IFDEF LCODE
  1156. __dskspace      PROC    far
  1157. ELSE
  1158. __dskspace      PROC    near
  1159. ENDIF
  1160.  
  1161.                 push    bp
  1162.                 mov     bp,sp
  1163.                 push    di                      ; preserve register variable
  1164.  
  1165.                 mov     ah,36h                  ; get free disk space
  1166.                 mov     dl,byte ptr [bp+ARG_1]  ; drive code (0=default, 1=A)
  1167.                 int     21h
  1168.                 cmp     ax,0FFFFh               ; was drive invalid?
  1169.                 je      space1                  ; yes, jump
  1170.                 mul     cx                      ; bytes per sector *
  1171.                                                 ;  sectors per cluster
  1172. IFDEF LDATA
  1173.                 les     di,dword ptr [bp+ARG_1+2]
  1174.                 mov     es:[di],ax              ; bytes per cluster
  1175. ELSE
  1176.                 mov     di,word ptr [bp+ARG_1+2]
  1177.                 mov     ds:[di],ax              ; bytes per cluster
  1178. ENDIF
  1179. IFDEF LDATA
  1180.                 les     di,dword ptr [bp+ARG_1+6]
  1181.                 mov     es:[di],bx              ; number of available clusters
  1182. ELSE
  1183.                 mov     di,word ptr [bp+ARG_1+4]
  1184.                 mov     ds:[di],bx              ; number of available clusters
  1185. ENDIF
  1186.                 xor     ax,ax
  1187.  
  1188. space1:         pop     di                      ; restore register variable
  1189.                 pop     bp
  1190.                 ret
  1191.  
  1192. __dskspace      ENDP
  1193.  
  1194. ;
  1195. ; int _getrc( void );
  1196. ;
  1197.  
  1198.                 PUBLIC  __getrc
  1199. IFDEF LCODE
  1200. __getrc         PROC    far
  1201. ELSE
  1202. __getrc         PROC    near
  1203. ENDIF
  1204.  
  1205.                 mov     ah,4Dh                  ; get child return code
  1206.                 int     21h
  1207.  
  1208.                 ret
  1209.  
  1210. __getrc         ENDP
  1211.  
  1212. ;
  1213. ; int _create( char *, int * );
  1214. ;
  1215.  
  1216.                 PUBLIC  __create
  1217. IFDEF LCODE
  1218. __create        PROC    far
  1219. ELSE
  1220. __create        PROC    near
  1221. ENDIF
  1222.  
  1223.                 push    bp
  1224.                 mov     bp,sp
  1225. IFDEF LDATA
  1226.                 push    ds
  1227. ENDIF
  1228.  
  1229.                 mov     ax,3000h                ; get DOS version number
  1230.                 int     21h
  1231. IFDEF LDATA
  1232.                 lds     dx,dword ptr [bp+ARG_1] ; file
  1233. ELSE
  1234.                 mov     dx,word ptr [bp+ARG_1]  ; file
  1235. ENDIF
  1236.                 xor     cx,cx                   ; normal attribute
  1237.                 mov     ah,5Bh                  ; create new file
  1238.                 cmp     al,3                    ; major version number
  1239.                 jae     create1
  1240.                 mov     ah,3Ch                  ; create file
  1241.  
  1242. create1:        int     21h
  1243.                 jc      create2
  1244. IFDEF LDATA
  1245.                 lds     bx,dword ptr [bp+ARG_1+4] ; handle address
  1246. ELSE
  1247.                 mov     bx,word ptr [bp+ARG_1+2] ; handle address
  1248. ENDIF
  1249.                 mov     ds:[bx],ax
  1250.                 xor     ax,ax
  1251.  
  1252. create2:
  1253. IFDEF LDATA
  1254.                 pop     ds
  1255. ENDIF
  1256.                 pop     bp
  1257.                 ret
  1258.  
  1259. __create        ENDP
  1260.  
  1261. ;
  1262. ; int _getcd( int, char * );
  1263. ;
  1264.  
  1265.                 PUBLIC  __getcd
  1266. IFDEF LCODE
  1267. __getcd         PROC    far
  1268. ELSE
  1269. __getcd         PROC    near
  1270. ENDIF
  1271.  
  1272.                 push    bp
  1273.                 mov     bp,sp
  1274.                 push    si                      ; preserve register variable
  1275. IFDEF LDATA
  1276.                 push    ds
  1277. ENDIF
  1278.  
  1279.                 mov     dl,byte ptr [bp+ARG_1]  ; drive code (0=default, 1=A)
  1280. IFDEF LDATA
  1281.                 lds     si,dword ptr [bp+ARG_1+2] ; buffer
  1282. ELSE
  1283.                 mov     si,word ptr [bp+ARG_1+2] ; buffer
  1284. ENDIF
  1285.                 mov     ah,47h                  ; get current directory
  1286.                 int     21h
  1287.                 jc      getcd1
  1288.                 xor     ax,ax
  1289.  
  1290. getcd1:
  1291. IFDEF LDATA
  1292.                 pop     ds
  1293. ENDIF
  1294.                 pop     si                      ; restore register variable
  1295.                 pop     bp
  1296.                 ret
  1297.  
  1298. __getcd         ENDP
  1299.  
  1300. ;
  1301. ; int _getdrv( void );
  1302. ;
  1303.  
  1304.                 PUBLIC  __getdrv
  1305. IFDEF LCODE
  1306. __getdrv        PROC    far
  1307. ELSE
  1308. __getdrv        PROC    near
  1309. ENDIF
  1310.  
  1311.                 mov     ah,19h                  ; get default disk drive
  1312.                 int     21h
  1313.                 xor     ah,ah
  1314.  
  1315. ; AX = drive (0 = A, 1 = B, etc.)
  1316.  
  1317.                 ret
  1318.  
  1319. __getdrv        ENDP
  1320.  
  1321. ;
  1322. ; void _getvect( int, unsigned int *, unsigned int * );
  1323. ;
  1324.  
  1325.                 PUBLIC  __getvect
  1326. IFDEF LCODE
  1327. __getvect       PROC    far
  1328. ELSE
  1329. __getvect       PROC    near
  1330. ENDIF
  1331.  
  1332.                 push    bp
  1333.                 mov     bp,sp
  1334.                 push    ds
  1335.                 push    si                      ; preserve register variable
  1336.  
  1337.                 mov     ah,35h                  ; get interrupt vector
  1338.                 mov     al,byte ptr [bp+ARG_1]  ; interrupt number
  1339.                 int     21h
  1340. IFDEF LDATA
  1341.                 lds     si,dword ptr [bp+ARG_1+2]
  1342. ELSE
  1343.                 mov     si,word ptr [bp+ARG_1+2]
  1344. ENDIF
  1345.                 mov     ds:[si],es              ; segment
  1346. IFDEF LDATA
  1347.                 lds     si,dword ptr [bp+ARG_1+6]
  1348. ELSE
  1349.                 mov     si,word ptr [bp+ARG_1+4]
  1350. ENDIF
  1351.                 mov     ds:[si],bx              ; offset
  1352.  
  1353.                 pop     si                      ; restore register variable
  1354.                 pop     ds
  1355.                 pop     bp
  1356.                 ret
  1357.  
  1358. __getvect       ENDP
  1359.  
  1360. ;
  1361. ; void _setvect( VECTOR * );
  1362. ;
  1363.  
  1364.                 PUBLIC  __setvect
  1365. IFDEF LCODE
  1366. __setvect       PROC    far
  1367. ELSE
  1368. __setvect       PROC    near
  1369. ENDIF
  1370.  
  1371.                 push    bp
  1372.                 mov     bp,sp
  1373.                 push    ds                      ; modified in setvectsub
  1374.  
  1375. IFDEF LDATA
  1376.                 les     bx,dword ptr [bp+ARG_1] ; vector table
  1377. ELSE
  1378.                 mov     bx,word ptr [bp+ARG_1]  ; vector table
  1379.                 push    ds
  1380.                 pop     es
  1381. ENDIF
  1382.  
  1383.                 call    setvectsub
  1384.  
  1385.                 pop     ds
  1386.                 pop     bp
  1387.                 ret
  1388.  
  1389. __setvect       ENDP
  1390.  
  1391. _TEXT           ENDS
  1392.  
  1393.                 END
  1394.